<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><%= productName %></title>
  
  <!-- 强制使用CDN加载Vue和Element Plus -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <script src="https://unpkg.com/element-plus"></script>
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  
  <!-- 重置和基础样式 -->
  <style>
    body, html {
      margin: 0;
      padding: 0;
      height: 100%;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", "sans-serif";
      overflow: hidden;
    }
    
    #app {
      width: 100%;
      height: 100%;
      position: relative;
      overflow: hidden;
      margin: 0;
      padding: 0;
      display: block;
      box-sizing: border-box;
      text-align: left; /* 确保对齐 */
      background-color: #ffffff; /* 默认白色背景 */
    }
    
    /* 加载和错误状态 */
    .miniblink-error, .miniblink-loading {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background-color: rgba(255, 255, 255, 0.9);
      z-index: 9999;
    }
    .miniblink-error-title, .miniblink-loading-title {
      font-size: 20px;
      font-weight: bold;
      margin-bottom: 16px;
      color: #333;
    }
    .miniblink-error-message {
      font-size: 14px;
      color: #f56c6c;
      margin-bottom: 16px;
      text-align: center;
      max-width: 80%;
    }
    .miniblink-loading-spinner {
      width: 40px;
      height: 40px;
      border: 4px solid #f3f3f3;
      border-top: 4px solid #409eff;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      margin-bottom: 16px;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    
    /* 组件的绝对定位 */
    [data-component-id] {
      box-sizing: border-box !important;
      position: absolute !important;
    }
    
    /* 单选框和多选框组样式 */
    .el-radio-group, .el-checkbox-group {
      display: flex !important;
      flex-wrap: wrap !important;
      gap: 5px !important;
      align-items: flex-start !important;
    }
    
    /* 确保组内元素样式与设计时保持一致 */
    .el-radio-group > .el-radio, 
    .el-checkbox-group > .el-checkbox,
    .el-radio-group > [data-component-id], 
    .el-checkbox-group > [data-component-id] {
      position: relative !important;
      margin: 0 !important;
      width: auto !important; /* 明确指定auto，不使用100% */
      height: auto !important; /* 明确指定auto，不使用100% */
      flex-shrink: 0 !important;
      /* 覆盖绝对定位 */
      top: auto !important;
      left: auto !important;
      z-index: auto !important;
      /* 明确禁止使用100%宽高 */
      max-width: none !important;
      max-height: none !important;
    }
    
    /* 确保单选框和多选框元素本身不使用100%宽高 */
    .el-radio, .el-checkbox {
      width: auto !important;
      height: auto !important;
    }
    
    /* 强制 #app 尺寸 */
    #app {
        box-sizing: border-box !important; 
    }
    
    /* 自定义组件样式 */
    <% if (typeof componentStyles === 'string' && componentStyles.length > 0) { %>
      <style id="custom-styles">
        <%- componentStyles %>
      </style>
    <% } %>
  </style>
</head>
<body>
  <div id="app">
    <!-- Vue App will be mounted here -->
    <div class="miniblink-loading">
      <div class="miniblink-loading-spinner"></div>
      <div class="miniblink-loading-title">加载中...</div>
    </div>
  </div>

  <script>
    // --- Communication Bridge (miniBridge) --- 保留不变
    window.miniBridge = {
      _eventHandlers: {},
      on: function(eventName, handler) {
        if (!this._eventHandlers[eventName]) {
          this._eventHandlers[eventName] = [];
        }
        this._eventHandlers[eventName].push(handler);
        console.log(`Registered handler for event: ${eventName}`);
        return this;
      },
      off: function(eventName, handler) {
        if (!this._eventHandlers[eventName]) return this;
        if (handler) {
          const index = this._eventHandlers[eventName].indexOf(handler);
          if (index !== -1) {
            this._eventHandlers[eventName].splice(index, 1);
          }
        } else {
          delete this._eventHandlers[eventName];
        }
        return this;
      },
      emit: function(eventName, data) {
        console.log(`Emitting event: ${eventName}`, data);
        try {
          if (window.external && typeof window.external.CallCSharpOrOther === 'function') {
            const message = JSON.stringify({ event: eventName, data: data || {} });
            window.external.CallCSharpOrOther(message);
          } else {
            console.warn(`No host bridge available for event: ${eventName}`);
          }
        } catch (error) {
          console.error(`Error emitting event ${eventName}:`, error);
        }
        return this;
      },
      _handleHostMessage: function(message) {
        try {
          const { event, data } = typeof message === 'string' ? JSON.parse(message) : message;
          console.log(`Received host event: ${event}`, data);
          if (this._eventHandlers[event]) {
            this._eventHandlers[event].forEach(handler => {
              try { handler(data); } catch (handlerError) { console.error(`Error in handler for ${event}:`, handlerError); }
            });
          }
        } catch (error) {
          console.error('Error processing host message:', error);
        }
      }
    };
    window.MiniblinkCallback = function(messageStr) {
      try { window.miniBridge._handleHostMessage(messageStr); } catch (error) { console.error('Error in MiniblinkCallback:', error); }
    };
    
    // --- Global App State --- 修改：使用更健壮的 JSON 解析方式
    let initialState = { components: [], canvasSize: { width: 800, height: 600 } };
    try {
       const initialStateJSON = <%- JSON.stringify({ components: components || [], canvasSize: canvasSize || { width: 800, height: 600 } }) %>;
       initialState = JSON.parse(JSON.stringify(initialStateJSON)); // 深拷贝一层以防万一
       console.log('[Init] Parsed initialState:', initialState);
    } catch (e) {
       console.error('[Init] Failed to parse initial state JSON:', e);
       // 使用默认值
    }
    
    window.appState = Vue.reactive({
      components: initialState.components,
      componentStates: {}, 
      canvasSize: initialState.canvasSize,
      errorMessage: null,
      isLoading: true
    });
    
    // --- Error Handling --- 保留不变
    function handleError(error, errorTitle = '错误') {
      console.error('App error:', error);
      const appDiv = document.getElementById('app');
      const errorDiv = document.createElement('div');
      errorDiv.className = 'miniblink-error';
      errorDiv.innerHTML = `
        <div class="miniblink-error-title">${errorTitle}</div>
        <div class="miniblink-error-message">${error.message || String(error)}</div>
      `;
      if (appDiv) appDiv.appendChild(errorDiv);
      if (window.miniBridge) window.miniBridge.emit('app:error', { message: error.message || String(error), stack: error.stack });
      window.appState.errorMessage = error.message || String(error);
      window.appState.isLoading = false;
      const loadingEl = document.querySelector('.miniblink-loading');
      if (loadingEl) loadingEl.style.display = 'none';
    }

    // 初始化设置 #app 尺寸
    function setAppSize() {
      if (!window.appState.canvasSize) return;
      const appEl = document.getElementById('app');
      if (appEl) {
        appEl.style.setProperty('width', `${window.appState.canvasSize.width}px`, 'important');
        appEl.style.setProperty('height', `${window.appState.canvasSize.height}px`, 'important');
        console.log(`设置app尺寸为: ${window.appState.canvasSize.width}x${window.appState.canvasSize.height}`);
      }
    }

    // --- Vue App Initialization --- 修改
    function initializeApp() {
      try {
        if (typeof Vue === 'undefined' || typeof ElementPlus === 'undefined') {
          throw new Error('Vue或Element Plus未加载，请检查网络连接或CDN是否可用');
        }
        
        const { createApp, h, resolveComponent, reactive, computed, onMounted, nextTick } = Vue;
        
        // 移除所有手动实现的组件 (ElButton, ElInput, ElSwitch, etc.)
        
        // DynamicRenderer component - 使用 resolveComponent
        const DynamicRenderer = {
          name: 'DynamicRenderer',
          props: {
            component: { type: Object, required: true }
          },
          setup(props) {
            // 组件状态代理
            const componentState = computed({
              get: () => window.appState.componentStates[props.component.id],
              set: (value) => {
                window.appState.componentStates[props.component.id] = value;
                // 通知宿主 (可选，如果需要实时同步)
                window.miniBridge.emit('component:change', {
                  componentId: props.component.id,
                  value: value
                });
              }
            });
            return { componentState };
          },
          render() {
            if (!this.component || !this.component.type) {
              console.error('Invalid component:', this.component);
              return null;
            }
            
            const resolvedComponent = resolveComponent(this.component.type);
            let propsData = Object.assign({}, this.component.props || {});
            const events = {};
            const componentId = this.component.id;
            const componentType = this.component.type;
            
            // 处理datas对象，如果存在则展开到propsData中
            if (propsData.datas && typeof propsData.datas === 'object') {
              // 将datas对象的内容合并到propsData中
              const datasContent = propsData.datas;
              Object.keys(datasContent).forEach(key => {
                propsData[key] = datasContent[key];
              });
              // 移除原始的datas属性，避免在HTML中显示为[object Object]
              delete propsData.datas;
            }
            
            // --- 事件绑定 (保持之前的简化逻辑) --- 
            events.onClick = (event) => {
              console.log(`Click triggered for ${componentId}`);
              window.miniBridge.emit('component:event', { componentId: componentId, eventName: 'click' });
              if(event) event.stopPropagation();
            };
            if (this.component.events) {
              for (const eventName in this.component.events) {
                if (eventName.toLowerCase() === 'click') continue;
                const callbackName = this.component.events[eventName];
                const nativeEventName = `on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`;
                events[nativeEventName] = (eventOrValue) => {
                  const value = typeof eventOrValue === 'object' && eventOrValue !== null && eventOrValue.target ? eventOrValue.target.value : eventOrValue;
                  console.log(`Event ${eventName} triggered for ${componentId}`);
                  window.miniBridge.emit('component:event', { componentId: componentId, eventName: eventName, callbackName: callbackName, value: value });
                };
              }
            }
            
            // --- v-model 状态初始化与绑定 (保持之前的逻辑) --- 
            if (window.appState.componentStates[componentId] === undefined) {
              let defaultValue = propsData.modelValue ?? propsData.value ?? null;
              if (defaultValue === null) {
                  if (componentType === 'el-switch' || componentType === 'el-checkbox') defaultValue = propsData.inactiveValue ?? propsData.falseLabel ?? false;
                  else if (componentType === 'el-slider' || componentType === 'el-rate') defaultValue = 0;
                  else if (componentType === 'el-input-number') defaultValue = propsData.min ?? 0;
              }
              window.appState.componentStates[componentId] = defaultValue;
            }
            const vModelProps = {
                modelValue: this.componentState,
                'onUpdate:modelValue': (value) => { this.componentState = value; }
            };
            
            // --- 子节点/插槽处理 (再次调整按钮) --- 
            let defaultSlotContent = null; 
            if (this.component.children && this.component.children.length > 0) {
              defaultSlotContent = this.component.children.map(child => {
                const isInsideGroup = componentType === 'el-radio-group' || componentType === 'el-checkbox-group';
                return h(DynamicRenderer, { component: child, key: child.id, isInsideGroup: isInsideGroup });
              });
            } 
            else if (propsData.textContent) {
                defaultSlotContent = propsData.textContent;
                delete propsData.textContent;
            } 
            else if (componentType === 'el-button') {
                defaultSlotContent = propsData.label || propsData.text || '按钮'; // 提供默认值
                // console.log(`Button ${componentId} text: ${defaultSlotContent}`);
                // 从 props 移除，避免潜在冲突
                delete propsData.label;
                delete propsData.text;
            } else if (componentType === 'el-tag') {
                 defaultSlotContent = propsData.label || propsData.text || propsData.content || '';
            }
            
            // --- 最终 Props 和 h() 调用 --- 
            let style = this.component.style || {};
            if (this.$attrs.isInsideGroup) {
                // 提取并删除 left, top, position 属性
                var left = style.left;
                var top = style.top;
                var position = style.position;
                var restStyle = Object.assign({}, style);
                delete restStyle.left;
                delete restStyle.top;
                delete restStyle.position;
                
                style = Object.assign({}, restStyle, { position: 'relative' }); 
            } 
            else if (componentType === 'el-radio-group' || componentType === 'el-checkbox-group') {
                 style = Object.assign({}, style, { 
                    display: 'flex', 
                    flexDirection: 'row', 
                    flexWrap: 'wrap', 
                    // 减小间距，使其更接近设计时的效果
                    gap: '5px' 
                 });
            }
            
            const finalProps = Object.assign({}, 
                propsData || {}, 
                events || {}, 
                {'data-component-id': componentId, style: style}, 
                vModelProps || {});
            if (finalProps.value !== undefined && finalProps.modelValue !== undefined) delete finalProps.value;
            
            let finalThirdParam = undefined; // h() 的第三个参数
            
            if (componentType === 'el-select' && propsData.options) {
                // Select options
                finalThirdParam = { 
                    default: () => propsData.options.map(option => 
                        h(resolveComponent('el-option'), { key: option.value, label: option.label, value: option.value, disabled: option.disabled })
                    )
                };
            } else if (componentType === 'el-button' && typeof defaultSlotContent === 'string') {
                // **关键修复：按钮文本直接创建 span VNode 作为第三参数**
                finalThirdParam = h('span', defaultSlotContent);
            } else if (Array.isArray(defaultSlotContent)) {
                // 子 VNode 数组
                finalThirdParam = { default: () => defaultSlotContent };
            } else if (typeof defaultSlotContent === 'string') {
                 // 其他组件的文本内容
                 finalThirdParam = { default: () => defaultSlotContent }; // 放入插槽
            }
             
            // console.log(`Rendering ${componentId} (${componentType}) H Third Param:`, finalThirdParam);
            return h(resolvedComponent, finalProps, finalThirdParam);
          }
        };
        
        // App component - 保持大致结构，使用新的 DynamicRenderer
        const App = {
          setup() {
            const state = reactive({
              rootComponent: null,
              errorMessage: window.appState.errorMessage
            });
            
            onMounted(() => {
              try {
                  // 初始化组件状态
                  if (Array.isArray(window.appState.components)) {
                      window.appState.components.forEach(comp => {
                          if (window.appState.componentStates[comp.id] === undefined) {
                              window.appState.componentStates[comp.id] = comp.props?.modelValue ?? comp.props?.value ?? (comp.type === 'el-switch' ? false : null);
                          }
                      });
                  }
                  
                // 创建根容器
                state.rootComponent = {
                  id: 'root',
                  type: 'div',
                  style: `width: 100%; height: 100%; position: relative; left: 0; top: 0; margin: 0; padding: 0; overflow: hidden;`, // 确保容器撑满
                  children: Array.isArray(window.appState.components) ? window.appState.components.map(comp => {
                    // 处理自定义组件类型，将ew-前缀转换为el-前缀
                    if (comp && comp.type && typeof comp.type === 'string' && comp.type.startsWith('ew-')) {
                      return {...comp, type: comp.type.replace('ew-', 'el-')};
                    }
                    return comp;
                  }) : [] // 确保是数组
                };
                
                // 使用 nextTick 确保 DOM 就绪后再设置尺寸
                nextTick(() => {
                    setAppSize();
                });
                
                window.appState.isLoading = false;
                const loadingEl = document.querySelector('.miniblink-loading');
                if (loadingEl) loadingEl.style.display = 'none';
                
                // 订阅宿主消息
                window.miniBridge.on('updateComponents', (newComponents) => {
                  console.log('Updating components from host:', newComponents);
                  window.appState.components = newComponents || [];
                  // 重建根组件以反映变化
                  state.rootComponent = {
                    id: 'root',
                    type: 'div',
                    style: `width: 100%; height: 100%; position: relative; left: 0; top: 0; margin: 0; padding: 0; overflow: hidden;`,
                    children: Array.isArray(window.appState.components) ? window.appState.components.map(comp => {
                      // 处理自定义组件类型，将ew-前缀转换为el-前缀
                      if (comp && comp.type && typeof comp.type === 'string' && comp.type.startsWith('ew-')) {
                        return {...comp, type: comp.type.replace('ew-', 'el-')};
                      }
                      return comp;
                    }) : []
                  };
                  // 可能需要重新初始化状态
                });
                window.miniBridge.on('updateComponentState', (data) => {
                    if(data && data.componentId && data.value !== undefined) {
                        console.log(`Updating state for ${data.componentId}:`, data.value);
                        window.appState.componentStates[data.componentId] = data.value;
                    }
                });
                window.miniBridge.on('error', (error) => {
                  handleError(error, 'Host Error');
                });
                
                // 发送就绪信号
                window.miniBridge.emit('ready');
                console.log('Vue application initialized and ready.');
                
              } catch (initError) {
                handleError(initError, '应用初始化失败');
              }
            });
            
            return () => {
              if (state.errorMessage) {
                return h('div', { class: 'miniblink-error' }, [
                  h('div', { class: 'miniblink-error-title' }, '错误'),
                  h('div', { class: 'miniblink-error-message' }, state.errorMessage)
                ]);
              }
              if (!state.rootComponent) {
                 return h('div', { class: 'miniblink-loading' }, [
                  h('div', { class: 'miniblink-loading-spinner' }),
                  h('div', { class: 'miniblink-loading-title' }, '加载中...')
                ]);
              }
              return h(DynamicRenderer, { component: state.rootComponent });
            };
          }
        };
        
        // Create and mount the app, using ElementPlus
        const app = createApp(App);
        app.use(ElementPlus); // 使用全局 ElementPlus
        app.mount('#app');
        
      } catch (error) {
        handleError(error, '应用核心初始化失败');
      }
    }
    
    // Start initialization on DOMContentLoaded
    document.addEventListener('DOMContentLoaded', function() {
        // 不再需要 checkDependencies 和 loadMissingDependencies
        initializeApp();
    });

  </script>
</body>
</html> 